using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Windows.Forms;
using UmlDesigner.Gui;

namespace UmlDesigner.Model
{
    [Serializable]
    class FolderWidget : ClassWidget
    {
        public FolderWidget()
        {
            size.Width += 60;
            size.Height -= 40;
        }

//        public string name = null;

        Color folderStartGradient = Color.FromArgb(248, 237, 164);
        Color folderEndGradient = Color.FromArgb(227, 205, 20);
        Color folderOutlineColour = Color.FromArgb(57, 52, 13);

        private const int folderTabWidth = 100;

        internal override bool IsPointWithin(Point p)
        {
            return ClassRect.Contains(p);
        }

        float[] pattern = new float[2];

        internal override void PaintSelectionOutline(Graphics e)
        {
            Pen stippledPen = new Pen(Color.Black);
            DrawSelection(e, stippledPen);
        }

        private void DrawSelection(Graphics e, Pen stippledPen)
        {
            Rectangle selClassRect = ClassRect;
            selClassRect.Width += 8;
            selClassRect.Height += 8;
            selClassRect.X -= 4;
            selClassRect.Y -= 4;
            pattern[0] = 5.0f;
            pattern[1] = 5.0f;
            stippledPen.DashPattern = pattern;

            Point[] pts = new Point[6];
            pts[0] = new Point(selClassRect.X, selClassRect.Y);
            pts[1] = new Point(selClassRect.X + folderTabWidth + 8, selClassRect.Y);
            pts[2] = new Point(selClassRect.X + folderTabWidth + 8, selClassRect.Y + 30);
            pts[3] = new Point(selClassRect.X + selClassRect.Width, selClassRect.Y + 30);
            pts[4] = new Point(selClassRect.X + selClassRect.Width, selClassRect.Y + selClassRect.Height);
            pts[5] = new Point(selClassRect.X, selClassRect.Y + selClassRect.Height);
            //            pts[0] = new Point(selClassRect.X, selClassRect.Y);

            e.DrawPolygon(stippledPen, pts);
        }

        public override void HandleFocusedOutline(Graphics g)
        {
            Pen stippledPen = new Pen(Color.BlueViolet, 2);
            DrawSelection(g, stippledPen);
        }

        internal override void PaintItem(Graphics e)
        {
            //if (!Properties.Settings.Default.FixedWidthClassWidgets)
            //{
            //    ItemSize = new Size((int)e.MeasureString(name, SystemFonts.DefaultFont).Width + 20, ItemSize.Height);
            //}
            //else
            //{
            //    // TODO: need to cut down excessively long strings, and center the result.
            //}

            Point point = Position;
            Rectangle classRect = ClassRect;
            Rectangle classBodyRect = classRect;
            classBodyRect.Y += 30;
            classBodyRect.Height = ClassRect.Height - 30;
            classBodyRect.Width = ClassRect.Width;

            classRect.Width = folderTabWidth;

            Color outlineColour = folderOutlineColour;
            Pen outlinePen = new Pen(outlineColour);
            SolidBrush topFill = new SolidBrush(folderStartGradient);
            LinearGradientBrush classBkgd = new LinearGradientBrush(classBodyRect, folderStartGradient, folderEndGradient, 45.0f);

            e.FillRectangle(topFill, classRect);
            e.DrawRectangle(outlinePen, classRect);

            e.FillRectangle(classBkgd, classBodyRect);
            e.DrawRectangle(outlinePen, classBodyRect);

            e.DrawString(name, SystemFonts.DefaultFont, new SolidBrush(Color.Black), new Point(Position.X + 10, Position.Y + 10));
        }


        internal void ShallowCopyFolderWidget(FolderWidget target)
        {
            target.name = name;
            ShallowCopyItemWidget(target);
        }

        public override void HandleDoubleClicked(UmlControl ctrl)
        {
            FolderPropertiesForm dlg = new FolderPropertiesForm(this);
            dlg.ShowDialog();
        }

        internal override bool ItemWithinArea(Rectangle rect)
        {
            return ClassRect.IntersectsWith(rect);
        }

        internal override bool IsFolder()
        {
            return true;
        }

        internal override bool IsClass()
        {
            return false;
        }

        internal override void GenerateCode(CodeGenerationSettings settings)
        {
            string finalDir = settings.OutputDirectory + "\\" + name;
            Directory.CreateDirectory(finalDir);
            StreamWriter writer = new StreamWriter(finalDir + "\\I" + name + ".cs", false, Encoding.ASCII);

            CodeGenerationSettings ifcSettings = new CodeGenerationSettings(finalDir, settings.DefaultNamespace + "." + name, CodeGenerationSettings.GenerationSource.SelectionOnly, false, false, false);
            ifcSettings.StartNewItem(writer, 0);

            string oldClassName = name;
            name = "I" + name;
            base.GenerateCodeStub(ifcSettings);
            name = oldClassName;

            ifcSettings.FinishCurrentItem();
        }

        internal override string GetClassName()
        {
            return name;
        }

        internal override void Dump(TreeNode parent)
        {
            parent.Nodes.Add("Folder: " + name + " {" + GetHashCode() + "}");
        }
    }
}
